const express = require('express')
const app = express()


const server = require('http').createServer(app);
const io = require("socket.io")(server, {
    cors: {
        // origin: "http://127.0.0.1:8080",
        origin: "*",
        methods: ["GET", "POST"]
    }
});


// io.set('origins', '*:*');
// io.set("Access-Control-Allow-Origin", "*");
// io.set("Access-Control-Allow-Headers", "X-Requested-With,Content-type,token");
// io.set("Access-Control-Allow-Methods", "PUT,POST,GET,DELETE,OPTIONS");
// io.set("X-Powered-By", ' 3.2.1');
// io.set("Content-Type", "application/json;charset=utf-8");

const connObj = require("./sqlconn")
const doToken = require("./token")

let env = process.env.NODE_ENV;
const port_listen = connObj.getconn(env).port_listen;
console.log(connObj.getconn(env))
const bodyParser = require('body-parser');

class User {
    constructor(token, username, password) {
        this.token = token;
        this.username = username;
        this.password = password;
        this.id = "";
        this.email = "";
        this.expires = "";
        this.fabu = "";
        this.remark = "";
    }
    async getUser(callback) {
        let results;
        if (this.token) {
            results = await connObj.query(`select * from yonghu where token = '${this.token}'`)
        } else {
            results = await connObj.query(`select * from yonghu where username = '${this.username}' and password = '${this.password}'`)
        }
        if (results.length) {
            this.id = results[0].id;
            this.email = results[0].email;
            this.expires = results[0].expires;
            this.fabu = results[0].fabu;
            this.token = results[0].token;
            return callback(this)
        } else {
            return callback(null);
        }
    }
}
// 配置body-parser模块
app.use(bodyParser.urlencoded({
    extended: false,
}));

app.use(bodyParser.json())
var mysql = require('mysql');
// const { delDiancan } = require('../src/utils/api');

var connection = mysql.createConnection(connObj.getconn(env));
try {
    connection.connect();
    console.log("mysql连接成功",connection)
} catch (error) {
    console.log("mysql连接报错",error)
}



app.all("/*", function (req, res, next) {
    // 跨域处理
    // DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range
    res.header("Access-Control-Allow-Origin", "*");
    // res.header("Access-Control-Allow-Headers", "X-Requested-With,Content-type,token");
    res.header("Access-Control-Allow-Headers", "DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range,token");
    res.header("Access-Control-Allow-Methods", "PUT,POST,GET,DELETE,OPTIONS");
    res.header("X-Powered-By", '3.2.1');
    res.header("Content-Type", "application/json;charset=utf-8");

    // res.header("Access-Control-Allow-Origin", "*");
    // res.header('Access-Control-Allow-Headers', 'Content-type,token');
    // res.header("Access-Control-Allow-Methods", "PUT,POST,GET,DELETE,OPTIONS,PATCH");
    // res.header('Access-Control-Max-Age',1728000);//预请求缓存20天
    // res.header("Access-Control-Allow-Headers","token")

    if (req.headers.accept == "application/json" || req.headers.accept == "application/x-www-form-urlencoded") {
        if (req.headers.token || req.originalUrl == "/user/login") {
            next(); // 执行下一个路由
        } else {
            res.send({
                code: -1,
                msg: "token为空，请重新登录",
                data: {
                    token: req.headers.token,
                }
            })
        }
    } else {
        next();
    }


})
app.post('/ceshi', (req, res) => {
    console.log("/")
    res.send('Hello World!' + getLocalIP())
})
app.post("/user/getUserInfo", (req, res) => {
    let token = req.headers.token;
    try {
        let obj = doToken.verifytoken(token)
        res.send({
            code: 200,
            msg: "",
            data: {
                token: "",
                user: obj
            }
        })
    } catch (error) {
        res.send({
            code: 200,
            msg: "",
            data: {
                token: "",
                user: ""
            }
        })
    }

})
app.post("/user/login", (req, res) => {
    let username = req.body["username"];
    let password = req.body["password"];
    new User("", username, password).getUser(user => {
        let token = doToken.gettoken(user)
        if (!user) {
            token = user
        }
        res.send({
            code: 200,
            msg: "",
            data: {
                token: token,
            }
        })
    })
})

app.post('/admin/addFood', (req, res) => {
    // res.send('Hello World!123')
    let foodName = req.body["foodName"]
    connection.query(`insert into caipin values(null,'${foodName}','是','')`, function (error, results, fields) {
        if (error) throw error;
        res.send(results)

    });
})

app.post('/admin/delFood', (req, res) => {
    // res.send('Hello World!123')
    let foodName = req.body["foodName"]
    connection.query(`delete from caipin where caipin = '${foodName}'`, function (error, results, fields) {
        if (error) throw error;
        res.send(results)

    });
})

app.post('/admin/fabu', (req, res) => {
    // res.send('Hello World!123')
    let nowDay = getTimeByTimeZone(8).Format("yyyy-MM-dd");
    let nowTime = req.body["nowTime"]
    let startTime = req.body["startTime"]
    let endTime = req.body["endTime"]
    let caipin = req.body["caipinSelectArr"]
    let faburen = req.body["faburen"]
    let remark = req.body["remark"]
    console.log(`${faburen}发布了信息`)
    connection.query(`insert into detail values(null,'${nowDay}','${startTime}','${endTime}','${caipin}','${faburen}','${nowTime}','${remark}')`, function (error, results, fields) {
        if (error) throw error;
        checkFabuToClient(io, "new");
        res.send(results)

    });
})
app.post('/admin/delFabu', (req, res) => {
    // res.send('Hello World!123')
    let nowDay = getTimeByTimeZone(8).Format("yyyy-MM-dd");
    let faburen = req.body["faburen"]
    console.log(`${faburen}删除了今日发布信息`)
    connection.query(`delete from detail where DATE_FORMAT(riqi,'%Y-%m-%d') = '${nowDay}' `, function (error, results, fields) {
        if (error) throw error;
        res.send(results)

    });
})

app.post('/admin/addUser', (req, res) => {
    // res.send('Hello World!123')
    let username = req.body["username"]
    console.log(`准备添加${username}用户信息`)
    console.log(`insert into yonghu values(null,'${username}','123456','${username}@etekcity.com.cn','',null,'','')`)
    connection.query(`insert into yonghu values(null,'${username}','123456','${username}@etekcity.com.cn','',null,'','')`, function (error, results, fields) {
        if (error) throw error;
        if (results.affectedRows == 1) {
            console.log(`成功添加${username}用户信息`)
        } else {
            console.log(`没有添加${username}用户信息`)
        }
        res.send(results)

    });
})

function delDiancan(req, res) {
    let nowDay = getTimeByTimeZone(8).Format("yyyy-MM-dd");
    let diancanren = req.body["diancanren"]
    console.log(`准备删除${diancanren}点餐信息`)
    connection.query(`delete from user where DATE_FORMAT(riqi,'%Y-%m-%d') = '${nowDay}' and username = '${diancanren}'`, function (error, results, fields) {
        if (error) throw error;
        if (results.affectedRows == 1) {
            console.log(`成功删除${diancanren}今日点餐信息`)
            getFoodsToClient()
        } else {
            console.log(`没有${diancanren}今日点餐信息`)
        }
        res.send(results)

    });
}
app.post('/admin/delDiancan', (req, res) => {
    delDiancan(req, res)
})
app.post('/user/delDiancanMe', (req, res) => {
    delDiancan(req, res)
})

app.post('/user/diancan', (req, res) => {
    // res.send('Hello World!123')
    let riqi = req.body["riqi"]
    let tjtime = req.body["tjtime"]
    let diancanren = req.body["diancanren"]
    let caipinSelectArr = req.body["caipinSelectArr"]
    console.log(`${diancanren}点餐了${caipinSelectArr}`)
    connection.query(`delete from user where username = '${diancanren}' and  DATE_FORMAT(riqi,'%Y-%m-%d') = '${riqi}'`, function (error, results, fields) {
        connection.query(`insert into user values(null,'${diancanren}','${caipinSelectArr}','${riqi}','${tjtime}','是','')`, function (error, results, fields) {
            if (error) throw error;
            getFoodsToClient()
            res.send(results)
        });
    });


})

app.post('/user/getFoods', (req, res) => {
    connection.query(`select * from caipin`, function (error, results, fields) {
        if (error) throw error;
        res.send(results)
    });
})

app.post('/user/getYonghu', (req, res) => {
    connection.query(`select * from yonghu`, function (error, results, fields) {
        if (error) throw error;
        res.send(results)
    });
})

app.post('/user/getDiancan', (req, res) => {
    let nowDay = getTimeByTimeZone(8).Format("yyyy-MM-dd");
    console.log(`select username,caipin,DATE_FORMAT(riqi,'%Y-%m-%d') as riqi from user where riqi = '${nowDay}'`)
    connection.query(`select username,caipin,DATE_FORMAT(riqi,'%Y-%m-%d') as riqi from user where riqi = '${nowDay}'`, function (error, results, fields) {
        if (error) throw error;
        res.send(results)
    });
})

app.post('/user/getFabu', (req, res) => {
    let nowDay = getTimeByTimeZone(8).Format("yyyy-MM-dd");
    connection.query(`select id,DATE_FORMAT(riqi,'%Y-%m-%d') as riqi,DATE_FORMAT(startTime,'%Y-%m-%d %T') as startTime,DATE_FORMAT(endTime,'%Y-%m-%d %T') as endTime,caipin,faburen,DATE_FORMAT(tjTime,'%Y-%m-%d %T') as tjTime,remark from detail   where riqi = '${nowDay}' order by id desc LIMIT 1`, function (error, results, fields) {
        if (error) throw error;
        res.send(results)
    });
})

app.get('/user/ceshi', (req, res) => {
    // res.send('Hello World!123')
    connection.query('SELECT * from caipin', function (error, results, fields) {
        if (error) throw error;
        res.send(results)
    });
})
var getFoodsToClient = () => {
    let nowDay = getTimeByTimeZone(8).Format("yyyy-MM-dd");
    connection.query(`select * from user where DATE_FORMAT(riqi,'%Y-%m-%d') = '${nowDay}'`, (error, results, fields) => {
        io.emit("getFoodsToClient", {
            list: results,
            nowDay: nowDay
        })
    })
}
let fabuObj = null
var checkOverTime = (io) => {
    if (fabuObj == null) {
        checkFabuToClient(io)
        setTimeout(() => {
            checkOverTime(io);
        }, 5000)
        return;
    }
    let bjTime = getTimeByTimeZone(8).Format("yyyy-MM-dd hh:mm:ss")
    let nowTime = new Date(
        bjTime.allReplace("-", "/")
    );
    let endTime = new Date(fabuObj.endTime.allReplace("-", "/"));
    let startTime = new Date(fabuObj.startTime.allReplace("-", "/"));
    let daojishi = 0;
    if (startTime > nowTime) {
        //还未开始
        daojishi = (startTime - nowTime) / 1000;
    }
    if (nowTime - startTime > 0 && endTime - nowTime > 0) {
        //还未结束
        daojishi = (endTime - nowTime) / 1000;
    }
    console.log('checkOverTime1', daojishi * 1000)
    if (daojishi < 0) {
        daojishi = 0;
    }
    setTimeout(() => {
        console.log('开始执行')
        checkFabuToClient(io)
    }, (daojishi + 1) * 1000)
}
var checkFabuToClient = (io, type) => {
    let nowDay = getTimeByTimeZone(8).Format("yyyy-MM-dd");
    connection.query(`select id,DATE_FORMAT(riqi,'%Y-%m-%d') as riqi,DATE_FORMAT(startTime,'%Y-%m-%d %T') as startTime,DATE_FORMAT(endTime,'%Y-%m-%d %T') as endTime,caipin,faburen,DATE_FORMAT(tjTime,'%Y-%m-%d %T') as tjTime,remark from detail   where riqi = '${nowDay}' order by id desc LIMIT 1`, function (error, results, fields) {
        if (error) throw error;
        let bjTime = getTimeByTimeZone(8).Format("yyyy-MM-dd hh:mm:ss")
        let nowTime = new Date(
            bjTime.allReplace("-", "/")
        );
        if (!results.length) {
            io.emit("checkFabuToClient", {
                fabu: false,
                type: type
            })
            return;
        }
        fabuObj = results[0];
        let endTime = new Date(fabuObj.endTime.allReplace("-", "/"));
        let startTime = new Date(fabuObj.startTime.allReplace("-", "/"));
        let daojishi = 0;
        let kedian = false;
        let tishi = ""
        if (nowTime - startTime > 0 && endTime - nowTime > 0) {
            daojishi = (endTime - nowTime) / 1000;
            kedian = true;
        } else {
            console.log("over");
            if (nowTime - startTime > 0) {
                tishi = `根据最新的发布信息，今天点餐已经结束，下次请早，如需加餐，请联系发布人${fabuObj.faburen}`;
                daojishi = -1;
            } else {
                tishi = `根据最新的发布信息，今天点餐还未开始`;
                daojishi = (startTime - nowTime) / 1000;
            }

            kedian = false;
        }

        io.emit("checkFabuToClient", {
            fabu: true,
            nowTime: nowTime,
            fabuObj: fabuObj,
            daojishi: daojishi,
            kedian: kedian,
            tishi: tishi,
            type: type
        })
        if (daojishi > 0) {
            console.log('checkOverTime2', daojishi * 1000)
            setTimeout(() => {
                checkFabuToClient(io)
            }, (daojishi + 1) * 1000)
        }
        // res.send(results)
    });
}

io.on('connection', socket => {
    checkOverTime(io)
    // 监听客户端发送的信息
    socket.on("reciveClient", message => {
        // 给客户端返回信息
        message += "qin"
        io.emit("sendToClient", {
            message
        });
    });
    // 监听客户端发送的信息
    socket.on("checkFabuToClient", message => {
        checkFabuToClient(io, "");
    });

    // socket.on("getFoodsToClient", message => {
    //     checkFabuToClient(io,message);
    // });
    // 监听连接断开事件
    socket.on("disconnect", (error) => {
        // io.emit("disconnect", "over");
        console.log("连接已断开...");
    });
    socket.on("connect", (error) => {
        // io.emit("disconnect", "over");
        console.log("连接已连接...");
    });
});
server.listen(port_listen, () => console.log(`Example app listening on port ${port_listen} !`))
// var socket = io.listen(server,{origins: '*:*'}); 
// socket.on('connection', function (client) {

//     sys.puts("New client is here!");
//     client.send("hello world");

//     client.on('message', function (msg) { sys.puts("client has sent:" + msg); });
//     client.on('disconnect', function () { sys.puts("Client has disconnected"); });

//     //发送自定义事件
//     client.emit('news', { hello: 'news world' });

//     //临听自定义事件
//     client.on('my other event', function (data) {
//         //console.log(data);
//     });
// });

function getLocalIP() {
    const os = require('os');
    const ifaces = os.networkInterfaces();
    let locatIp = '';
    for (let dev in ifaces) {
        if (dev === 'WLAN') {
            for (let j = 0; j < ifaces[dev].length; j++) {
                if (ifaces[dev][j].family === 'IPv4') {
                    locatIp = ifaces[dev][j].address;
                    break;
                }
            }
        }
    }
    return locatIp;
}

String.prototype.allReplace = function (f, e) { //吧f替换成e
    var reg = new RegExp(f, "g"); //创建正则RegExp对象   
    return this.replace(reg, e);
}
Date.prototype.Format = function (fmt) { //author: meizz 
    var o = {
        "M+": this.getMonth() + 1, //月份 
        "d+": this.getDate(), //日 
        "h+": this.getHours(), //小时 
        "m+": this.getMinutes(), //分 
        "s+": this.getSeconds(), //秒 
        "q+": Math.floor((this.getMonth() + 3) / 3), //季度 
        "S": this.getMilliseconds() //毫秒 
    };
    if (/(y+)/.test(fmt)) fmt = fmt.replace(RegExp.$1, (this.getFullYear() + "").substr(4 - RegExp.$1.length));
    for (var k in o)
        if (new RegExp("(" + k + ")").test(fmt)) fmt = fmt.replace(RegExp.$1, (RegExp.$1.length == 1) ? (o[k]) :
            (("00" + o[k]).substr(("" + o[k]).length)));
    return fmt;
}

function getTimeByTimeZone(timeZone) {
    var d = new Date();
    localTime = d.getTime(),
        localOffset = d.getTimezoneOffset() * 60000, //获得当地时间偏移的毫秒数,这里可能是负数
        utc = localTime + localOffset, //utc即GMT时间
        offset = timeZone, //时区，北京市+8  美国华盛顿为 -5
        localSecondTime = utc + (3600000 * offset); //本地对应的毫秒数
    var date = new Date(localSecondTime);
    console.log("根据本地时间得知" + timeZone + "时区的时间是 " + date.toLocaleString());
    console.log("系统默认展示时间方式是：" + date)
    return date;
}